package com.freemalll.merchant.common;

import org.springframework.lang.Nullable;

import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;

/**
 * @author <a href="https://github.com/TAKETODAY">Harry Yang</a>
 * @since 1.0 2021/12/16 15:42
 */
public interface Enumerable<V> {

    // 存往数据库的值，暂定字符串类型（可能后期存在性能问题，暂不考虑）， 默认就是枚举的名字

    @SuppressWarnings("unchecked")
    default V getValue() {
        return (V) name();
    }

    String getDescription(); // 描述 对标 BaseEnum#getValue

    String name(); // 枚举默认的名字 , 该方法无需实现，枚举类自动继承

    @Nullable
    static <T extends Enumerable<V>, V> T introspect(Class<T> enumerable, V value) {
        T[] enumConstants = enumerable.getEnumConstants();
        if (enumConstants != null) {
            for (T constant : enumConstants) {
                if (Objects.equals(value, constant.getValue())) {
                    return constant;
                }
            }
        }
        return null;
    }

    /**
     * @param defaultValue 默认值
     */
    static <T extends Enumerable<V>, V> T introspect(Class<T> enumerable, V value, Supplier<T> defaultValue) {
        return optional(enumerable, value).orElseGet(defaultValue);
    }

    static <T extends Enumerable<V>, V> Optional<T> optional(Class<T> enumerable, V value) {
        return Optional.ofNullable(introspect(enumerable, value));
    }

}
